<?php
abstract class validatableinput extends htmlwidget {
	protected $label;
	//$variable to store the answer
	public $answer;
	
	//if necessary to provide a default answer
	public $defaultAnswer;
			
	//to store the modified answer if any, v.g. encrypted password
	public $modifiedAnswer;
		
	//if the type is select, the options will be stored here (array)
	public $answerOptions;
	
	//a regex to validate the answer
	public $validRegex;
	
	//min and max lenghts, only check if <> 0
	public $maxLength = 0;
	public $minLength = 0;
	
	//error message to display 
	public $errorMessage;
	
	//success of failure
	public $failed = 0;
	
	//has this question been validated already?
	public $hasBeenValidated = 0;
	
	//if the answer needs to match the answer of another question
	//example  password and password_confirmation
	public $nameToMatch = '';
	
	//if we need to apply a function to the answer, v.g. md5(answer)
	public $callFunction;

	//escape or no escape the answer
	public $escape; // (true|false)
	
	//this are the only valid characters
	public $validcharacters;
	
	//if there are characters to avoid
	public $invalidCharacters;

	//if there are characters that must exist
	public $requiredCharacters;
	
	//use a captcha?
	public $captcha;
	
	public $reusepost = 1;
	
	public $requiresValidation = true;
	

	

	public function fail(){
		$this->failed = 1;
	}
	
	public function isValid(){
		return ($this->failed == 0)? 1:0;
	}

	public function setCaptcha($obj){
		$this->captcha = $obj;
	}
	
	public function skipValidation(){
		$this->requiresValidation = false;
	}
	
	public function validate(){	
		if ( ! $this->requiresValidation ){
			return 1;
		}
		if ( $this->hasBeenValidated ){
			return $this->isValid();			
		} else {
			$this->hasBeenValidated = 1;
		}

		if ( empty($_POST)){
			return 1;
		} 
		
		$name = $this->attributes['name'];
		if (  strlen($name) && isset($_POST[$name]) ) {
			$this->answer = $_POST[$name];
			if ( ! empty($this->callfunction)){
				$this->modifiedAnswer = call_user_func($this->callfunction, $this->answer);
			}
			
			if ( ! empty( $this->minLength) ){
				if ( strlen($this->answer) < $this->minLength ){
					$this->errorMessage = 'Insuficient number of characters.';
					$this->fail();
					return $this->isValid();
				}
			}
			
			if ( ! empty( $this->maxLength) ){
				if ( strlen($this->answer) > $this->maxLength ){
					$this->errorMessage = 'Too many characters. Please shorten your answer.';
					$this->fail();
					return $this->isValid();
				}
			}
			
			if ( is_array($this->invalidCharacters) && count( $this->invalidCharacters)){
				foreach ( $this->invalidCharacters as $char ){
					if ( strpos($this->answer, $char)){
						$this->errorMessage = 'Your answer contains at least one invalid character.';
						$this->fail();
						return $this->isValid();						
					}
				}
			}
			
			if ( is_array($this->requiredCharacters) && count( $this->requiredCharacters)){
				foreach ( $this->requiredCharacters as $char ){
					if ( ! strpos($this->answer, $char)){
						$this->errorMessage = 'Your answer seems to be invalid.';
						$this->fail();
						return $this->isValid();						
					}
				}
			}	
			
			if ( is_array($this->validcharacters) && count( $this->validcharacters)){
				$mycharacters = preg_split("//", $this->answer, null, PREG_SPLIT_NO_EMPTY);
				$mycharacters = array_unique($mycharacters);
				foreach ( $mycharacters as $char ){
					if ( ! in_array($char, $this->validcharacters) ) {
						$this->errorMessage = 'Your answer seems to be invalid. The character <b>' . $char . '</b> is not valid.';
						$this->fail();
						return $this->isValid();						
					}
				}
			}
						
			if ( isset($this->validRegex)  && strlen($this->validRegex)){
				if ( ! preg_match($this->validRegex, $this->answer )){
					if ( strlen ($this->errorMessage)){
						//error already set
					} else {
						$this->errorMessage = 'Invalid answer.';
					}
					$this->fail();
					return $this->isValid();		
				}
			}

			if ( ! empty($this->nametomatch)){
				if ( ! isset( $_POST[$this->nametomatch] )){
					$this->errorMessage = $this->attributes['name'] . ' and  ' . $this->nametomatch . ' don\'t match.';
					$this->fail();
					return $this->isValid();
				}
				
				if (  $this->answer != $_POST[$this->nametomatch] ){
					$this->errorMessage = $this->attributes['name'] . ' and ' . $this->nametomatch . ' don\'t match.';
					$this->fail();
					return $this->isValid();
				}
			}

			if ( $this->captcha instanceof captcha){
				if ( ! $this->captcha->verify($this->answer)){
					$this->errorMessage = 'Captcha verification failed.';
					$this->fail();
					return $this->isValid();					
				}
			}
			
			return $this->isValid();
		} else {
			$this->fail();
			$this->errorMessage = 'You failed to provide an ansere for the field (' . $name . ')' ;
			return $this->isValid();
		}
	}

	public function getLabel(){
	        return $this->label;
	}
	
	
	public function getAnswer(){
	        return $this->answer;
	}
	
	
	public function getdefaultAnswer(){
	        return $this->defaultAnswer;
	}
	
	public function getValidRegex(){
	        return $this->validRegex;
	}
	
	
	public function getErrorMessage(){
	        return $this->errorMessage;
	}
	
	public function getAnsweroptions(){
		return $this->answeroptions;
	}
	
	public function getNametomatch(){
		return $this->nametomatch;
	}
	
	
	public function getCallfunction(){
		return $this->callfunction;
	}
	
	
	public function getmodifiedAnswer(){
		if ( empty ($this->callfunction)){
			return $this->answer;
		} else {
			if ( ! empty($this->modifiedAnswer)){
				return $this->modifiedAnswer;
			} else {
				$this->modifiedAnswer = call_user_func($this->callfunction, $this->answer);
				return $this->modifiedAnswer;
			}
		}
	}

	
	public function getEscape(){
		if ( isset($this->escape)){
			if ( $this->escape == 1 || $this->escape == true){
				return true;
			} else {
				return false;
			}
		} else {
			return false;
		}
	}
	
	public function getInvalidCharacters(){
		return $this->invalidCharacters;
	}
	
	public function getmaxLength(){
		return $this->maxLength;
	}
	
	public function getminLength(){
		return $this->minLength;
	}
	
	public function setLabel($label){
		$this->label = $label;
	}
	
	
	public function setAnswer($answer){
		$this->answer = $answer;
	}
	
	
	public function setdefaultAnswer($defaultAnswer){
		$this->defaultAnswer = $defaultAnswer;
	}
	
	
	public function setValidRegex($validRegex){
		$this->validRegex = $validRegex;
	}
	
	
	public function setErrorMessage($errormsg){
		$this->errorMessage = $errormsg;
	}
	
	
	public function setAnsweroptions($answeroptions){
		$this->answeroptions = $answeroptions;
	}
	

	public function setNametoMatch($nametomatch){
		$this->nametomatch = $nametomatch;
	}
	
	
	public function setCallfunction($callfunction){
		$this->callfunction = $callfunction;
	}
	
	
	public function setmodifiedAnswer($modifiedAnswer){
		$this->modifiedAnswer = $modifiedAnswer;
	}
	
	
	public function setEscape($escape){
		$this->escape = $escape;
	}
	
	public function setInvalidCharacters($chars){		
		if ( is_array($chars)){
			$this->invalidCharacters = $chars;
		} elseif ( is_scalar($chars)){
			if ( strpos($chars, 'a-z')){
				$chars = str_replace("a-z", 'abcdefghijklmnopqrstuvwxyz', $chars);
			}
			if ( strpos($chars, 'A-Z')){
				$chars = str_replace("A-Z", 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', $chars);
			}
			$this->invalidCharacters = preg_split("//", $chars, null, PREG_SPLIT_NO_EMPTY);
		}
		$this->invalidCharacters = array_unique($this->invalidCharacters);
	}
	
	public function setValidCharacters($chars){
		if ( is_array($chars)){
			$this->validCharacters = $chars;
		} elseif ( is_scalar($chars)){
			if ( strpos($chars, 'a-z')){
				$chars = str_replace("a-z", 'abcdefghijklmnopqrstuvwxyz', $chars);
			}
			if ( strpos($chars, 'A-Z')){
				$chars = str_replace("A-Z", 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', $chars);
			}			
			$this->validCharacters = preg_split("//", $chars, null, PREG_SPLIT_NO_EMPTY);
		}
		$this->validCharacters = array_unique($this->validCharacters);
	}	
	
	public function setmaxLength($length){
		$this->maxLength = $length;
	}
	
	public function setminLength($length){		
		$this->minLength = $length;
	}
	
	public function setReusePost($val){
		$this->reusepost = $val;
	}
}
?>